import { defineStore } from 'pinia';
import { storage } from '@/utils';
import { ACCESS_TOKEN, CURRENT_USER } from './../mutation-types';
import { store } from '@/stores';
import to from 'await-to-js';
import { ResultEnum } from '@/enums/httpEnum';
import { PageEnum } from '@/enums/pageEnum';
import loginApi from '@/api/modules/login';
import userApi from '@/api/modules/user';
import { storageExpireTime } from '@/settings/commonSetting';
import router from '@/router';
import { cloneDeep } from 'lodash-es';
import type { ICustomWindow } from '@/plugin/naive-ui';

export type UserInfoType = {
  name: string;
  age?: string;
  email?: string;
  userId?: string;
  account?: Object;
  bindings?: Object[];
  profile?: Object;
  [key: string]: any;
};

export interface IUserStoreState {
  token: string;
  userId: string;
  userName: string;
  userAvatar: string;
  userInfo: UserInfoType;
}

const $message = (window as unknown as ICustomWindow)['$message'];

export const useUserStore = defineStore({
  id: 'app-user',
  state: (): IUserStoreState => ({
    token: storage.get(ACCESS_TOKEN),
    userId: '',
    userName: '',
    userAvatar: '',
    userInfo: storage.get(CURRENT_USER),
  }),
  getters: {
    getToken(state): string {
      return state.token;
    },
    getUserName(): string {
      return this.userName;
    },
    getUserAvatar(): string {
      return this.userAvatar;
    },
    getUserInfo(): UserInfoType {
      return this.userInfo;
    },
  },
  actions: {
    setToken(token: string) {
      this.token = token;
      storage.set(ACCESS_TOKEN, token, storageExpireTime);
    },
    setUserAvatar(userAvatar: string) {
      this.userAvatar = userAvatar;
    },
    setUserId(userId: string) {
      this.userId = userId;
    },
    setUserName(userName: string) {
      this.userName = userName;
    },
    setUserInfo(userInfo: UserInfoType) {
      this.userInfo = userInfo;
    },
    async login(params, mode: 'phone' | 'email' = 'phone') {
      const request = mode === 'phone' ? loginApi.loginByCellphone : loginApi.loginByEmail;
      const [error, resp] = await to(request(params));
      if (error || resp.code !== ResultEnum.SUCCESS) {
        $message.error(resp?.msg || error?.msg || error || '');
      }
      if (resp && resp.code === ResultEnum.SUCCESS) {
        const {
          account,
          bindings,
          token,
          profile: { userId, avatarUrl, nickname, ...profileOther },
        } = resp;
        const userInfo = cloneDeep(Object.assign({}, { name: nickname, account, bindings, profile: { userId, avatarUrl, nickname, ...profileOther } }));
        this.setToken(token ?? '');
        this.setUserId(userId ?? '');
        this.setUserAvatar(avatarUrl ?? '');
        this.setUserName(nickname ?? '');
        this.setUserInfo(userInfo);
        router?.replace({ path: PageEnum.BASE_MAIN });
        await this.getUserDetail();
      }
      return resp;
    },
    async getUserDetail() {
      const [error, resp] = await to(userApi.detail(this.userId));
      if (error || resp.code !== ResultEnum.SUCCESS) {
        $message.error(resp?.msg || error?.msg || error || '');
      }
      if (resp && resp.code === ResultEnum.SUCCESS) {
        const { code, ...otherInfo } = resp;
        const userInfo = Object.assign(this.getUserInfo, { ...otherInfo });
        this.setUserInfo(userInfo);
      }
    },
  },
  persist: {
    key: 'PINIA-APP-USER-STORE',
  },
});

export const useUserStoreOut = () => useUserStore(store);
